//
// Created by Administrator on 2022/3/9.
//

#ifndef TRANSACTION_DSL_C_TS_SCHED_H
#define TRANSACTION_DSL_C_TS_SCHED_H

#include <stdint.h>
#include "ts_action.h"
#include "defines/ts_bool.h"

typedef enum TsSchedType {
#include "sched_type_interpreter/ts_sched_type_interpreter_enum.h"
#include "ts_sched_type.h"
} TsSchedType;

typedef struct TsSched {
    uint8_t id;
    uint8_t numOfChildren;
    uint16_t rsv;
    TsAction action;
} TsSched;

///////////////////////////////////////////

typedef struct TsSchedContainer {
    uint16_t container_pc;
    uint16_t now_pc;
} TsSchedContainer;
/////////////////////////////////////////////
typedef struct TsSchedStack {
    uint16_t depth;
    uint16_t rsv;
    TsSchedContainer* stack;
} TsSchedStack;

typedef struct TsContext {
    TsSched* trans;
    void* userData;
    TsSchedStack stack;

    void* msg;
    TsStatus failStatus;
    TsBool isMsgConsumed;
} TsContext;
typedef TsContext* TsInstance;

/////////////////////////////////////////////
TsSchedContainer* TS_SCHED_STACK_Push(TsSchedStack* stack);
void TS_SCHED_STACK_Pop(TsSchedStack* stack);
TsSchedContainer* TS_SCHED_STACK_GetTop(TsSchedStack* stack);
TsBool TS_SCHED_STACK_IsTop(TsSchedContainer* container, TsSchedStack* stack);

/////////////////////////////////////////////
#define TS_INSTANCE_INIT_LEN (sizeof(TsContext))

#define DEF_SCHED_START_FUNC(type) TsStatus type##_Start(uint16_t pc, TsInstance instance)
#define DECL_SCHED_START_FUNC(type) DEF_SCHED_START_FUNC(type)
#define CALL_SCHED_START_FUNC(type) type##_Start

#define DEF_SCHED_HANDLE_EVENT_FUNC(type) TsStatus type##_HandleEvent(TsSchedContainer* container, TsInstance instance)
#define DECL_SCHED_HANDLE_EVENT_FUNC(type) DEF_SCHED_START_FUNC(type)
#define CALL_SCHED_HANDLE_EVENT_FUNC(type) type##_HandleEvent

#define INIT_SCHED(type, numOfChildren, exec, handler) {type, numOfChildren, 0, {exec, handler}}

#endif //TRANSACTION_DSL_C_TS_SCHED_H
